package com.ruoyi.safe.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.safe.domain.BizDutyRegion;
import com.ruoyi.safe.domain.BizRegionCooperator;
import com.ruoyi.safe.domain.CommonCooperator;
import com.ruoyi.safe.domain.CommonProject;
import com.ruoyi.safe.domain.dto.ProjectUserAndSuperiorsUserVO;
import com.ruoyi.safe.domain.dto.ProjectUserVO;
import com.ruoyi.safe.domain.dto.SuperiorsUserVO;
import com.ruoyi.safe.domain.dto.UserSearchDTO;
import com.ruoyi.safe.domain.vo.BizDutyRegionVO;
import com.ruoyi.safe.domain.vo.CommonUserVO;
import com.ruoyi.safe.domain.vo.ListRequestVo;
import com.ruoyi.safe.domain.vo.ManageUserVO;
import com.ruoyi.safe.mapper.CommonProjectMapper;
import com.ruoyi.safe.mapper.CommonUserMapper;
import com.ruoyi.system.domain.vo.UserMessageVO;
import com.ruoyi.safe.mapper.BizDutyRegionMapper;
import com.ruoyi.safe.mapper.CommonCooperatorMapper;
import com.ruoyi.safe.service.IBizDutyRegionService;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 责任区域Service业务层处理
 *
 * @author buxi
 * @date 2023-11-11
 */
@Service
public class BizDutyRegionServiceImpl implements IBizDutyRegionService {
    @Autowired
    private BizDutyRegionMapper bizDutyRegionMapper;
    @Autowired
    private CommonCooperatorMapper commonCooperatorMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private CommonProjectMapper commonProjectMapper;
    @Autowired
    private CommonUserMapper commonUserMapper;

    /**
     * 查询责任区域
     *
     * @param id 责任区域主键
     * @return 责任区域
     */
    @Override
    public BizDutyRegion selectBizDutyRegionById(Long id) {
        Optional<BizDutyRegion> optionalBizDutyRegion = Optional.ofNullable(bizDutyRegionMapper.selectBizDutyRegionById(id));

        return optionalBizDutyRegion.map(region -> {
            if (StringUtils.isNotBlank(region.getCooperatorId())) {
                List<Long> cooperatorIds = Arrays.stream(region.getCooperatorId().split(","))
                        .map(String::trim)
                        .map(Long::valueOf)
                        .collect(Collectors.toList());
                region.setCooperatorIds(cooperatorIds);
            }
            return region;
        }).orElse(null);
    }

    @Override
    public Long[] selectSelfAndChildrenBizDutyRegionIdsById(Long id) {
        BizDutyRegion bizDutyRegion = bizDutyRegionMapper.selectBizDutyRegionById(id);
        BizDutyRegion queryBizDutyRegion = new BizDutyRegion();
        queryBizDutyRegion.setProjectId(bizDutyRegion.getProjectId());
        List<BizDutyRegion> bizDutyRegions = bizDutyRegionMapper.selectBizDutyRegionList(queryBizDutyRegion);
        //递归查询所有子区域 包括自己
        Set<Long> ids = getChildrenRegion(bizDutyRegions, bizDutyRegion);
        //将所有子区域id放入数组
        ids.add(id);
        Long[] array = ids.toArray(new Long[0]);
        return array;
    }

    /**
     * 查询责任区域列表
     *
     * @param bizDutyRegion 责任区域
     * @return 责任区域
     */
    @Override
    public List<BizDutyRegion> selectBizDutyRegionList(BizDutyRegion bizDutyRegion) {

        if (StringUtils.isNotNull(bizDutyRegion.getProjectId())) {

            List<BizDutyRegion> bizDutyRegions = bizDutyRegionMapper.selectBizDutyRegionList(bizDutyRegion);

            bizDutyRegions.forEach(region -> Optional.ofNullable(region)
                    .filter(r -> StringUtils.isNotBlank(r.getCooperatorId()))
                    .ifPresent(r -> {
                        List<Long> cooperatorIds = Arrays.stream(r.getCooperatorId().split(","))
                                .map(String::trim)
                                .map(Long::valueOf)
                                .collect(Collectors.toList());
                        r.setCooperatorIds(cooperatorIds);
                    }));

            return bizDutyRegions;
        }

        return new ArrayList<>();
    }

    @Override
    public List<BizDutyRegionVO> selectBizDutyRegionListVO(BizDutyRegion bizDutyRegion) {

        if (StringUtils.isNotNull(bizDutyRegion.getProjectId())) {

            List<BizDutyRegionVO> bizDutyRegions = bizDutyRegionMapper.selectBizDutyRegionListVO(bizDutyRegion);

            List<CommonCooperator> commonCooperators1 = commonCooperatorMapper.selectCommonCooperatorList(new CommonCooperator());

            bizDutyRegions.forEach(region -> Optional.ofNullable(region)
                    .filter(r -> StringUtils.isNotBlank(r.getEnterpriseNames()))
                    .ifPresent(r -> {
                        List<Long> cooperatorIds = Arrays.stream(r.getEnterpriseNames().split(","))
                                .map(String::trim)
                                .map(Long::valueOf)
                                .collect(Collectors.toList());
                        List<String> enterpriseNames = commonCooperators1.stream().filter(commonCooperator -> cooperatorIds.contains(commonCooperator.getId())).map(CommonCooperator::getEnterpriseName).collect(Collectors.toList());
                        r.setCooperatorId(enterpriseNames);
                    }));

            return bizDutyRegions;
        }

        return new ArrayList<>();
    }

    /**
     * 新增责任区域
     *
     * @param bizDutyRegion 责任区域
     * @return 结果
     */
    @Override
    @Transactional
    public int insertBizDutyRegion(BizDutyRegion bizDutyRegion) {
        bizDutyRegion.setCreateTime(DateUtils.getNowDate());
        bizDutyRegion.setCreateBy(SecurityUtils.getUsername());
        int i = bizDutyRegionMapper.selectBizDutyRegionMaxSort(bizDutyRegion.getParentId(), bizDutyRegion.getProjectId());
        bizDutyRegion.setSort(i + 1);
        if (!CollectionUtils.isEmpty(bizDutyRegion.getCooperatorIds())) {
            bizDutyRegion.setCooperatorId(StringUtils.join(bizDutyRegion.getCooperatorIds(), ","));

            bizDutyRegionMapper.insertBizDutyRegion(bizDutyRegion);

            List<BizRegionCooperator> bizRegionCooperatorList = bizDutyRegion.getCooperatorIds().stream()
                    .map(cooperatorId -> {
                        BizRegionCooperator bizRegionCooperator = new BizRegionCooperator();
                        bizRegionCooperator.setRegionId(bizDutyRegion.getId());
                        bizRegionCooperator.setCooperatorId(cooperatorId);
                        return bizRegionCooperator;
                    }).collect(Collectors.toList());

            return bizDutyRegionMapper.insertRegionCooperator(bizRegionCooperatorList);
        }
        return bizDutyRegionMapper.insertBizDutyRegion(bizDutyRegion);
    }

    /**
     * 修改责任区域
     *
     * @param bizDutyRegion 责任区域
     * @return 结果
     */
    @Override
    @Transactional
    public int updateBizDutyRegion(BizDutyRegion bizDutyRegion) {
        bizDutyRegion.setUpdateTime(DateUtils.getNowDate());
        bizDutyRegion.setUpdateBy(SecurityUtils.getUsername());
        if (!CollectionUtils.isEmpty(bizDutyRegion.getCooperatorIds())) {
            bizDutyRegion.setCooperatorId(StringUtils.join(bizDutyRegion.getCooperatorIds(), ","));

            List<BizRegionCooperator> bizRegionCooperatorList = bizDutyRegion.getCooperatorIds().stream()
                    .map(cooperatorId -> {
                        BizRegionCooperator bizRegionCooperator = new BizRegionCooperator();
                        bizRegionCooperator.setRegionId(bizDutyRegion.getId());
                        bizRegionCooperator.setCooperatorId(cooperatorId);
                        return bizRegionCooperator;
                    }).collect(Collectors.toList());

            bizDutyRegionMapper.updateBizDutyRegion(bizDutyRegion);
            bizDutyRegionMapper.deleteRegionCooperatorByRegionId(bizDutyRegion.getId());
            return bizDutyRegionMapper.insertRegionCooperator(bizRegionCooperatorList);
        }

        bizDutyRegion.setCooperatorId(null);
        bizDutyRegionMapper.deleteRegionCooperatorByRegionId(bizDutyRegion.getId());
        return bizDutyRegionMapper.updateBizDutyRegion(bizDutyRegion);
    }

    /**
     * 批量删除责任区域
     *
     * @param ids 需要删除的责任区域主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteBizDutyRegionByIds(Long[] ids) {
        int i = 0;
        if(bizDutyRegionMapper.checkIds(ids)==0){
            List<BizDutyRegion> bizDutyRegions = bizDutyRegionMapper.selBizDutyRegionListByIds(ids);
            if (bizDutyRegions.isEmpty()) {
                throw new ServiceException("数据不存在");
            }
            Set<Long> children = new HashSet<>();
            List<BizDutyRegion> bizDutyRegions1 = bizDutyRegionMapper.selectBizDutyRegionList(new BizDutyRegion());
            bizDutyRegions.forEach(region -> {
                //删除所有子区域关联的合作单位
                children.addAll(getChildrenRegion(bizDutyRegions1, region));
            });
            children.addAll(Arrays.asList(ids));
            Long[] array = children.toArray(new Long[0]);
            bizDutyRegionMapper.deleteRegionCooperatorByRegionIds(array);
            i= bizDutyRegionMapper.deleteBizDutyRegionByIds(array);
        }
        return i;
    }

    /**
     * 删除责任区域信息
     *
     * @param id 责任区域主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteBizDutyRegionById(Long id) {
        BizDutyRegion bizDutyRegion = bizDutyRegionMapper.selectBizDutyRegionById(id);
        //查询所有区域列表
        BizDutyRegion bizDutyRegion2 = new BizDutyRegion();
        bizDutyRegion2.setProjectId(bizDutyRegion.getProjectId());
        List<BizDutyRegion> bizDutyRegions = bizDutyRegionMapper.selectBizDutyRegionList(bizDutyRegion2);
        //递归查询所有子区域 包括自己
        Set<Long> ids = getChildrenRegion(bizDutyRegions, bizDutyRegion);
        //将所有子区域id放入数组
        ids.add(id);
        Long[] array = ids.toArray(new Long[0]);
        //删除所有子区域关联的合作单位
        bizDutyRegionMapper.deleteRegionCooperatorByRegionIds(array);
        return bizDutyRegionMapper.deleteBizDutyRegionByIds(array);
    }

    @Override
    public int move(int moveType, Long id) {
        BizDutyRegion bizDutyRegion = bizDutyRegionMapper.selectBizDutyRegionById(id);
        BizDutyRegion bizDutyRegion1;
        List<BizDutyRegion> bizDutyRegions = new ArrayList<>();
        if (moveType == 1) {
            bizDutyRegion1 = bizDutyRegionMapper.selectBizDutyRegionBySortAndParentId(bizDutyRegion.getSort() - 1, bizDutyRegion.getParentId(), bizDutyRegion.getProjectId());
            if (bizDutyRegion1 == null) {
                throw new ServiceException("已经是第一条数据了");
            }
            bizDutyRegion.setSort(bizDutyRegion.getSort() - 1);
            bizDutyRegion1.setSort(bizDutyRegion1.getSort() + 1);
        } else {
            bizDutyRegion1 = bizDutyRegionMapper.selectBizDutyRegionBySortAndParentId(bizDutyRegion.getSort() + 1, bizDutyRegion.getParentId(), bizDutyRegion.getProjectId());
            if (bizDutyRegion1 == null) {
                throw new ServiceException("已经是最后一条数据了");
            }
            bizDutyRegion.setSort(bizDutyRegion.getSort() + 1);
            bizDutyRegion1.setSort(bizDutyRegion1.getSort() - 1);
        }
        bizDutyRegions.add(bizDutyRegion);
        bizDutyRegions.add(bizDutyRegion1);
        return bizDutyRegionMapper.updateBizDutyRegionSort(bizDutyRegions);
    }

    @Override
    public ManageUserVO selectBizDutyRegionByIdAndProjectId(ListRequestVo listRequestVo) {
        ManageUserVO manageUserVO = new ManageUserVO();

        BizDutyRegion bizDutyRegion = bizDutyRegionMapper.selectBizDutyRegionById(listRequestVo.getRegionId());
        if (StringUtils.isNull(bizDutyRegion)) {
            return manageUserVO;
        }
        if (StringUtils.isNotNull(bizDutyRegion.getCorrectorUserId())) {
            manageUserVO.setCorrectorUser(sysUserMapper.selectUserByUserId(bizDutyRegion.getCorrectorUserId()));
        }
        if (StringUtils.isNotNull(bizDutyRegion.getNotifierUserId())) {
            manageUserVO.setNotifierUser(sysUserMapper.selectUserByUserId(bizDutyRegion.getNotifierUserId()));
        }
        if (StringUtils.isNotNull(bizDutyRegion.getReviewerUserId())) {
            manageUserVO.setReviewerUser(sysUserMapper.selectUserByUserId(bizDutyRegion.getReviewerUserId()));
        }
        return manageUserVO;
    }

    @Override
    public ProjectUserAndSuperiorsUserVO higherAuthoritiesUsers(ListRequestVo listRequestVo) {

        ProjectUserAndSuperiorsUserVO projectUserAndSuperiorsUserVO = new ProjectUserAndSuperiorsUserVO();

        // 查询项目人员
        List<CommonUserVO> commonUserVOS = commonUserMapper.selectCommonUserList(UserSearchDTO.builder().projectId(listRequestVo.getProjectId()).build());
        List<Long> userIdsList = commonUserVOS.stream().map(CommonUserVO::getUserId).collect(Collectors.toList());

        // 查询项目人员信息
        List<UserMessageVO> userMessageVOS = sysUserMapper.selectUserMessageVOListByUserIds(StrUtil.join(",", userIdsList));

        // 查询上级部门人员
        CommonProject commonProject = commonProjectMapper.selectCommonProjectById(listRequestVo.getProjectId());

        // 查询上级部门
        SysDept parentDept = sysDeptMapper.selectSuperiorsDept(commonProject.getSigningDept());

        // 查询上级部门人员
        List<SysUser> sysUsers = sysUserMapper.selectUserByDeptId(parentDept.getDeptId());
        List<Long> superiorsUserIds = sysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList());

        // 查询上级部门人员信息
        List<UserMessageVO> userMessageVOS1 = sysUserMapper.selectUserMessageVOListByUserIds(StrUtil.join(",", superiorsUserIds));

        // 设置VO对象
        projectUserAndSuperiorsUserVO.setProjectUserVOList(Collections.singletonList(
                ProjectUserVO.builder()
                        .name(commonProject.getName())
                        .userMessageVOList(userMessageVOS)
                        .build()
        ));

        projectUserAndSuperiorsUserVO.setSuperiorsUserVOList(Collections.singletonList(
                SuperiorsUserVO.builder()
                        .name(parentDept.getDeptName())
                        .userMessageVOList(userMessageVOS1)
                        .build()
        ));

        return projectUserAndSuperiorsUserVO;
    }

    /**
     * 递归查询所有子区域id
     */
    public Set<Long> getChildrenRegion(List<BizDutyRegion> bizDutyRegions, BizDutyRegion bizDutyRegion) {
        Set<Long> children = new HashSet<>();
        for (BizDutyRegion region : bizDutyRegions) {
            if (region.getParentId().equals(bizDutyRegion.getId())) {
                children.add(region.getId());
                children.addAll(getChildrenRegion(bizDutyRegions, region));
            }
        }
        return children;
    }
}
